﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using accesoDatos;
using clasesBase;
using Logica;
using System.Data;

namespace PlanificacionProduccion
{
    public partial class FrmFormulasDet : FrmABM
    {
        private int idInstruccionSeleccionado = -1;
        ManejadorAyudas ayuda = new ManejadorAyudas();
        List<int> idItemsBorrar = new List<int>();
        List<int> idInstruccionesBorrar = new List<int>();
        Formula elem_formula = null;

        public FrmFormulasDet()
        {
            InitializeComponent();
        }

        private void form_Load(object sender, System.EventArgs e)
        {
            datosFases.DataSource = FaseItem.listarElementos(FaseItem.tablaBD);
            if (datosFases.Count > 0)
            {
                cmbFase.DisplayMember = "nombre";
                cmbFase.ValueMember = "id";
            }

            if (base.idElemento != 0) { 
                mostrarDatos();
            }

            btnImprimir.Enabled = (base.idElemento != 0);
        }

        private void mostrarDatos()
        {
            elem_formula = new Formula(base.idElemento);

            txtId.Text = elem_formula.ID.ToString();
            txtFecha.Text = elem_formula.Fecha.ToString();
            txtNombre.Text = elem_formula.Nombre.Trim();

            Producto producto = new Producto(elem_formula.IdProducto, false);
            txtProducto.Text = producto.Nombre.Trim();
            txtIdProducto.Text = producto.ID.ToString();
            
            txtObservacion.Text = elem_formula.Observacion.Trim();
            chkEsActual.Checked = elem_formula.FormulaActual;

            limpiarCamposItems();
            limpiarCamposInstrucciones();

            mostrarItems(elem_formula.Items);
            mostrarInstrucciones(elem_formula.Instrucciones);
        }

        private void btnGuardar_Click(object sender, System.EventArgs e)
        {
            quitarResaltado();
            if (camposCompletos())
            {
                if (Notificador.accionGuardarConfirmada())
                {
                    // Si se tratase de un elemento nuevo, el id correspondiente es 0.
                    int idElemento = txtId.Text.Trim() == "" ? 0 : Convert.ToInt32(txtId.Text);

                    Formula elem = new Formula(idElemento);
                    elem.Fecha = Convert.ToDateTime(txtFecha.Text);
                    elem.Nombre = txtNombre.Text.Trim();

                    int idProd = txtIdProducto.Text.Trim() == "" ? 0 : Convert.ToInt32(txtIdProducto.Text);
                    elem.IdProducto = idProd;

                    elem.Observacion = txtObservacion.Text.Trim();
                    elem.FormulaActual = chkEsActual.Checked;

                    elem.Items = obtenerItems();
                    elem.Instrucciones = obtenerInstrucciones();

                    // Guardo la información
                    string error = elem.guardar();
                    if (error == "")
                    {
                        /* Si la actualización fue realizada correctamente, continúo. Se deben eliminar, si existiesen, los items o
                         instrucciones que el usuario decidió borrar. */
                        foreach (int idElem in idItemsBorrar)
                        {
                            ItemFormula item = new ItemFormula();
                            item.ID = idElem;
                            error += " " + item.borrarElemento();
                        }

                        foreach (int idElem in idInstruccionesBorrar)
                        {
                            InstruccionFormula instruccion = new InstruccionFormula();
                            instruccion.ID = idElem;
                            error += " " + instruccion.borrarElemento();
                        }
                    }

                    Notificador.resultadoABM(idElemento == 0 ? TipoOperacionABM.ALTA : TipoOperacionABM.MODIFICACION, error.Trim());
                    if (error.Trim() == "") this.Close();
                }
            }
            else Notificador.camposNoCompletos();
        }

        private bool camposCompletos()
        {
            bool completos = true;

            if (txtNombre.Text.Trim() == "") { completos = false; lblNombre.ForeColor = Color.Red; }
            if (txtProducto.Text.Trim() == "") { completos = false; lblProducto.ForeColor = Color.Red; }
            if (grillaItems.Rows.Count == 0) { completos = false; grupoItems.ForeColor = Color.Red; }

            return completos;
        }

        private void quitarResaltado()
        {
            lblNombre.ForeColor = Color.Black;
            lblProducto.ForeColor = Color.Black;
            grupoItems.ForeColor = Color.Black;
        }

        private List<ItemFormula> obtenerItems()
        {
            List<ItemFormula> items = new List<ItemFormula>();
            int numOrdenInterno = 0;
            foreach (DataGridViewRow fila in grillaItems.Rows)
            {
                numOrdenInterno++;
                int idItem = Convert.ToInt32(fila.Cells["colIdItem"].Value);
                ItemFormula item = new ItemFormula(idItem);
                item.ObjMateriaPrima = new MateriaPrima(Convert.ToInt32(fila.Cells["colIdMateriaPrima"].Value));
                item.Cantidad = Convert.ToDecimal(fila.Cells["colCantidad"].Value);
                item.IdFormula = txtId.Text.Trim() == "" ? 0 : Convert.ToInt32(txtId.Text);
                item.NumeroOrden = Convert.ToInt32(fila.Cells["colOrden"].Value);
                item.NumeroOrdenInterno = numOrdenInterno;
                item.ObjFase = new FaseItem(Convert.ToInt32(fila.Cells["colIdFase"].Value));

                items.Add(item);
            }

            return items;
        }

        private void mostrarItems(List<ItemFormula> items)
        {
            grillaItems.Rows.Clear();
            foreach (ItemFormula elem in items)
                grillaItems.Rows.Add(elem.ID, elem.ObjMateriaPrima.ID, elem.ObjFase.ID, elem.NumeroOrden, elem.ObjMateriaPrima.Nombre.Trim(), elem.Cantidad, elem.ObjMateriaPrima.ObjUnidadMedida.Nombre.Trim());
        }

        private List<InstruccionFormula> obtenerInstrucciones()
        {
            List<InstruccionFormula> instrucciones = new List<InstruccionFormula>();
            int prioridad = 0;
            foreach (DataGridViewRow fila in grillaInstrucciones.Rows)
            {
                prioridad++;
                int idInstruccion = Convert.ToInt32(fila.Cells["colIdInstruccion"].Value);
                InstruccionFormula instruccion = new InstruccionFormula(idInstruccion);
                instruccion.Descripcion = fila.Cells["colInstruccion"].Value.ToString();
                instruccion.IdFormula = txtId.Text.Trim() == "" ? 0 : Convert.ToInt32(txtId.Text);
                instruccion.Prioridad = prioridad;

                instrucciones.Add(instruccion);
            }

            return instrucciones;
        }

        private void mostrarInstrucciones(List<InstruccionFormula> instrucciones)
        {
            grillaInstrucciones.Rows.Clear();
            foreach (InstruccionFormula elem in instrucciones)
                grillaInstrucciones.Rows.Add(grillaInstrucciones.Rows.Count, elem.ID, elem.Descripcion.Trim(), elem.Prioridad);
        }

        private void soloDecimales(object sender, KeyPressEventArgs e)
        {
            Validador.soloDecimales_KeyPress(sender, e);
        }

        private void soloEnteros(object sender, KeyPressEventArgs e)
        {
            Validador.soloEnteros_KeyPress(sender, e);
        }

        private void grilla_DoubleClick(object sender, EventArgs e)
        {
            DataGridView grilla = (DataGridView)sender;
            if (grilla.Rows.Count > 0)
            {
                switch (grilla.Name)
                {
                    case "grillaItems": mostrarItemSeleccionado();
                        break;
                    case "grillaInstrucciones": mostrarInstruccionSeleccionada();
                        break;
                    default:
                        break;
                }
            }
        }
        
        private void quitarFilaGrilla(DataGridView grilla)
        {
            DataGridViewRow filaSeleccionada = grilla.CurrentRow;
            if (filaSeleccionada != null)
            {
                if (Notificador.accionBorrarConfirmada())
                {
                    /* Confirmada la acción para borrar el elemento, guardo en primer lugar su id, ya que luego debería
                     * eliminarse en la tabla de la BD según corresponda. Si el id del elemento a borrarse es 0, no lo considero
                     * ya que se trata de un elemento nuevo y no existiría previamente para borrarlo. */
                    int id;
                    if (grilla.Name == "grillaItems") {
                        id = Convert.ToInt32(grilla.CurrentRow.Cells["colIdItem"].Value);
                        if (id != 0) idItemsBorrar.Add(id);
                    }

                    if (grilla.Name == "grillaInstrucciones")
                    {
                        id = Convert.ToInt32(grilla.CurrentRow.Cells["colIdInstruccion"].Value);
                        if (id != 0) idInstruccionesBorrar.Add(id);
                    }

                    grilla.Rows.RemoveAt(grilla.CurrentRow.Index);
                }
            }
            else Notificador.elementoNoSeleccionado();
        }

        #region Ayudas contextuales
        private void txtMateriaPrima_LostFocus(object sender, EventArgs e)
        {
            ayudaMateriaPrima(false);
        }

        private void ayudaMateriaPrima(bool todos)
        {
            if (!todos)
            {
                /* El evento ocurre a partir del elemento txtLocalidad. Valido antes de continuar, que haya algo escrito en localidad*/
                int id = txtIdMateriaPrima.Text.Trim() == "" ? 0 : Convert.ToInt32(txtIdMateriaPrima.Text);
                string materia = txtMateriaPrima.Text.Trim();
                lblUnidad.Text = "";

                ayuda.mostrarElementos(MateriaPrima.tablaBD, id, materia, true);
            }
            else ayuda.mostrarElementos(MateriaPrima.tablaBD);

            int idMatPrima = ayuda.IdSeleccionado;
            if (idMatPrima != 0)
            {
                MateriaPrima objMateria = new MateriaPrima(idMatPrima);
                lblUnidad.Text = objMateria.ObjUnidadMedida.Nombre.Trim();
            }

            txtIdMateriaPrima.Text = idMatPrima.ToString();
            txtMateriaPrima.Text = ayuda.NombreSeleccionado.Trim();
        }

        private void txtProducto_LostFocus(object sender, EventArgs e)
        {
            ayudaProductos(false);
        }

        private void ayudaProductos(bool todos)
        {
            if (!todos)
            {
                int id = txtIdProducto.Text.Trim() == "" ? 0 : Convert.ToInt32(txtIdProducto.Text);
                string materia = txtProducto.Text.Trim();

                ayuda.mostrarElementos(Producto.tablaBD, id, materia, true);
            }
            else ayuda.mostrarElementos(Producto.tablaBD);

            txtIdProducto.Text = ayuda.IdSeleccionado.ToString();
            txtProducto.Text = ayuda.NombreSeleccionado.Trim();
        }

        private void btnTodosProductos_Click(object sender, EventArgs e)
        {
            ayudaProductos(true);
        }

        private void btnTodosMateria_Click(object sender, EventArgs e)
        {
            ayudaMateriaPrima(true);
        }
        #endregion

        #region Items
        private void btnNuevoItem_Click(object sender, EventArgs e)
        {
            limpiarCamposItems();
        }

        private void limpiarCamposItems()
        {
            txtMateriaPrima.Text = "";
            txtIdMateriaPrima.Text = "";
            txtCantMatPrima.Text = "";
            lblUnidad.Text = "";
            txtOrden.Text = "";
            datosFases.MoveFirst();
        }

        private void mostrarItemSeleccionado()
        {
            DataGridViewRow filaSeleccionada = grillaItems.CurrentRow;
            if (filaSeleccionada != null)
            {
                txtMateriaPrima.Text = filaSeleccionada.Cells["colMateriaPrima"].Value.ToString();
                txtIdMateriaPrima.Text = filaSeleccionada.Cells["colIdMateriaPrima"].Value.ToString();
                txtCantMatPrima.Text = filaSeleccionada.Cells["colCantidad"].Value.ToString();
                lblUnidad.Text = filaSeleccionada.Cells["colUnidad"].Value.ToString();
                txtOrden.Text = filaSeleccionada.Cells["colOrden"].Value.ToString();
                cmbFase.SelectedValue = filaSeleccionada.Cells["colIdFase"].Value;
            }
        }

        private void btnAgregarItem_Click(object sender, EventArgs e)
        {
            int idMateriaPrima = txtIdMateriaPrima.Text.Trim() == "" ? 0 : Convert.ToInt32(txtIdMateriaPrima.Text);
            decimal cantidad = txtCantMatPrima.Text.Trim() == "" ? 0 : Convert.ToDecimal(txtCantMatPrima.Text);
            string unidadMedida = lblUnidad.Text;
            int idFase = cmbFase.SelectedValue != null ? (int)cmbFase.SelectedValue : 0;
            if (idMateriaPrima != 0 && cantidad != 0 && idFase != 0)
            {
                string nombreMatPrima = txtMateriaPrima.Text.Trim();
                int orden = txtOrden.Text.Trim() == "" ? 0 : Convert.ToInt32(txtOrden.Text);
                /* En primer lugar valido si ya se asoció a la fórmula algún item para la materia prima elegida. Si así fuera, sólo modifico la
                 * cantidad. En otro caso, creo un item nuevo y le asigno los valores iniciales. */
                DataGridViewRow fila = obtenerFilaGrilla(grillaItems, idMateriaPrima);
                if (fila != null) // Ya existe en la grilla una fila con ese idMateriaPrima
                {
                    fila.Cells["colCantidad"].Value = cantidad;
                    fila.Cells["colOrden"].Value = orden;
                    fila.Cells["colIdFase"].Value = idFase;
                }
                else grillaItems.Rows.Add(0, idMateriaPrima, idFase, orden, nombreMatPrima, cantidad, unidadMedida);

                limpiarCamposItems();
            }
            else Notificador.camposNoCompletos();
        }

        private DataGridViewRow obtenerFilaGrilla(DataGridView grilla, int idBuscado)
        {
            string columnaBuscar = "";
            if (grilla.Name == "grillaItems") columnaBuscar = "colIdMateriaPrima";
            else columnaBuscar = "colIdTemporal";

            DataGridViewRow fila;
            int indiceFilaBuscada = -1;
            for (int indiceFila = 0; indiceFila < grilla.Rows.Count; indiceFila++)
            {
                if ((int)grilla.Rows[indiceFila].Cells[columnaBuscar].Value == idBuscado)
                {
                    indiceFilaBuscada = indiceFila;
                    break;
                }
            }

            if (indiceFilaBuscada >= 0) fila = grilla.Rows[indiceFilaBuscada];
            else fila = null;

            return fila;
        }

        private void btnQuitar_Click(object sender, EventArgs e)
        {
            quitarFilaGrilla(grillaItems);
        }
        #endregion

        #region Instrucciones
        private void btnNuevaInstruccion_Click(object sender, EventArgs e)
        {
            limpiarCamposInstrucciones();
        }

        private void limpiarCamposInstrucciones()
        {
            txtInstruccion.Text = "";
            this.idInstruccionSeleccionado = -1;
        }

        private void mostrarInstruccionSeleccionada()
        {
            DataGridViewRow filaSeleccionada = grillaInstrucciones.CurrentRow;
            if (filaSeleccionada != null)
            {
                txtInstruccion.Text = filaSeleccionada.Cells["colInstruccion"].Value.ToString();
                this.idInstruccionSeleccionado = Convert.ToInt32(filaSeleccionada.Cells["colIdTemporal"].Value);
            }
        }

        private void btnAgregarInstruccion_Click(object sender, EventArgs e)
        {
            string instruccion = txtInstruccion.Text.Trim();
            if (instruccion != "")
            {
                DataGridViewRow fila = obtenerFilaGrilla(grillaInstrucciones, idInstruccionSeleccionado);
                if (fila != null) fila.Cells["colInstruccion"].Value = instruccion;
                else grillaInstrucciones.Rows.Add(grillaInstrucciones.Rows.Count, 0, instruccion);

                limpiarCamposInstrucciones();
            }
            else Notificador.camposNoCompletos();
        }

        private void btnQuitarInstruccion_Click(object sender, EventArgs e)
        {
            quitarFilaGrilla(grillaInstrucciones);
        }
        #endregion

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            int idElemento = txtId.Text.Trim() == "" ? 0 : Convert.ToInt32(txtId.Text);
            if (idElemento != 0)
            {
                BindingSource datos_formula = new BindingSource();
                datos_formula.DataSource = this.elem_formula;

                Impresion manejador = new Impresion();
                manejador.imprimirReporte(Datos_reportes.formula_ds, datos_formula, Datos_reportes.formula_rpt, false, false, this.Cursor, "", true, null, Datos_reportes.subreporte_formula_items, this);
            }
            else Notificador.elementoNoSeleccionado();
        }
    }
}